
#ifndef EffectParameter_h
#define EffectParameter_h

#include <System/Collections/Generic/List.h>
#include <System/Collections/Generic/Dictionary.h>
#include <System/Array.h>
#include <System/Single.h>
#include <System/ArgumentNullException.h>

#include "../Effect/EffectParameterClass.h"
#include "../Effect/EffectParameterType.h"
#include "../../RMatrix.h"
#include "../../RQuaternion.h"
#include "../Texture2D.h"
//#include "../Texture3D.h"
#include "EffectAnnotationCollection.h"


namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			// Not implemented.
			class Texture3D {};
			class TextureCube {};

			namespace Graphics
			{
				// Forward declerations.
				class EffectParameterCollection;

				//[DebuggerDisplay("{ParameterClass} {ParameterType} {Name} : {Semantic}")]
				class EffectParameter
				{
					/// <summary>
					/// The next state key used when an effect parameter
					/// is updated by any of the 'set' methods.
					/// </summary>
					public: /*internal*/ static ulong NextStateKey; // { get; private set; }

					public: /*internal*/ EffectParameter(   EffectParameterClass class_, 
												EffectParameterType type, 
												GC_PTR<Riccsson::System::string> name, 
												int rowCount, 
												int columnCount,
												GC_PTR<Riccsson::System::string> semantic, 
												GC_PTR<EffectAnnotationCollection> annotations,
												GC_PTR<EffectParameterCollection> elements,
												GC_PTR<EffectParameterCollection> structMembers,
												GC_PTR<Riccsson::System::object> data );

					public: /*internal*/ EffectParameter(EffectParameter* cloneSource);

					public: GC_PTR<Riccsson::System::string> Name;// { get; private set; }

					public: GC_PTR<Riccsson::System::string> Semantic;// { get; private set; }

					public: EffectParameterClass ParameterClass;// { get; private set; }

					public: EffectParameterType ParameterType;// { get; private set; }

					public: int RowCount;// { get; private set; }

					public: int ColumnCount;// { get; private set; }

					public: GC_PTR<EffectParameterCollection> Elements;// { get; private set; }

					public: GC_PTR<EffectParameterCollection> StructureMembers;// { get; private set; }

					public: GC_PTR<EffectAnnotationCollection> Annotations;// { get; private set; }


					// TODO: Using object adds alot of boxing/unboxing overhead
					// and garbage generation.  We should consider a templated
					// type implementation to fix this!

					public: /*internal*/ GC_PTR<Riccsson::System::Object> Data;;// { get; private set; }

					/// <summary>
					/// The current state key which is used to detect
					/// if the parameter value has been changed.
					/// </summary>
					public: /*internal*/ ulong StateKey;// { get; private set; }


					public: bool GetValueBoolean ();
					public: GC_PTR<Riccsson::System::Array<bool>> GetValueBooleanArray ();
					public: int GetValueInt32 ();
					public: GC_PTR<Riccsson::System::Array<int>> GetValueInt32Array ();
					public: Matrix GetValueMatrix ();
					public: GC_PTR<Riccsson::System::Array<Matrix>> GetValueMatrixArray (int count);
					public: Quaternion GetValueQuaternion ();
					public: GC_PTR<Riccsson::System::Array<Quaternion>> GetValueQuaternionArray ();
					public: System::Single GetValueSingle ();
					public: GC_PTR<Riccsson::System::Array<System::Single>> GetValueSingleArray ();
					public: GC_PTR<Riccsson::System::string> GetValueString ();
					public: GC_PTR<Texture2D> GetValueTexture2D ();
			#if !GLES
					public: GC_PTR<Texture3D> GetValueTexture3D ();
			#endif
					public: GC_PTR<TextureCube> GetValueTextureCube ();
					public: Vector2 GetValueVector2 ();
					public: GC_PTR<Riccsson::System::Array<Vector2>> GetValueVector2Array ();
					public: Vector3 GetValueVector3 ();
					public: GC_PTR<Riccsson::System::Array<Vector3>> GetValueVector3Array ();
					public: Vector4 GetValueVector4 ();
					public: GC_PTR<Riccsson::System::Array<Vector4>> GetValueVector4Array ();
					public: void SetValue (bool value);
					public: void SetValue (Riccsson::System::Array<bool>* value);
					public: void SetValue (int value);
					public: void SetValue (Riccsson::System::Array<int>* value);
					public: void SetValue(Matrix value);
					public: void SetValueTranspose(Matrix value);
					public: void SetValue (Riccsson::System::Array<Matrix>* value);
					public: void SetValue (Quaternion value);
					public: void SetValue (Riccsson::System::Array<Quaternion>* value);
					public: void SetValue (System::Single value);
					public: void SetValue (Riccsson::System::Array<System::Single>* value);
					public: void SetValue (Riccsson::System::string value);
					public: void SetValue (Texture value);
					public: void SetValue (Vector2 value);
					public: void SetValue (Riccsson::System::Array<Vector2>* value);
					public: void SetValue (Vector3 value);
					public: void SetValue (Riccsson::System::Array<Vector3>* value);
					public: void SetValue (Vector4 value);
					public: void SetValue (Riccsson::System::Array<Vector4>* value);
				};
			}
		}
	}
}

#endif